package multithread.lock;

/**
 * Created by xi on 2018/12/23.
 * 同步代码块使用monitorenter和monitorexit两个指令实现。可以把执行monitorenter指令理解为加锁，执行monitorexit理解为释放锁。 每个对象维护着一个记录着被锁次数的计数器。未被锁定的对象的该计数器为0，当一个线程获得锁（执行monitorenter）后，该计数器自增变为 1 ，当同一个线程再次获得该对象的锁的时候，计数器再次自增。当同一个线程释放锁（执行monitorexit指令）的时候，计数器再自减。当计数器为0的时候。锁将被释放，其他线程便可以获得锁。
 *
 * 实现方法是为每个锁关联一个线程持有者和计数器.
 * 可重入锁
 * 内存可见性
 * 原子性
 *
 *
 */
public class SynTest {
    //同步方法
    private Object lock = new Object();

    public synchronized void doSth(){
        System.out.println("Hello World");
    }

    public static void main(String[] args) {
        SynTest synTest = new SynTest();
        for(int i =0;i<10;i++){
            new Thread(new Runnable() {
                @Override public void run() {
                    synTest.doSth1();
                }
            }).start();
        }

    }
    public void doSth2(){
        synchronized (lock){
            System.out.println(Thread.currentThread().getName()+"Hello World2");
        }
    }
    //同步代码块
    public void doSth1(){
        synchronized (lock){
            System.out.println(Thread.currentThread().getName()+",Hello World");
            doSth2();
        }
    }

}
